# -*- coding: utf-8 -*-
import re
from repoze.bfg.chameleon_zpt import render_template
from repoze.bfg.interfaces import IResponseFactory, IView
from webob import Response
from zope.component import queryUtility
from zope.interface import alsoProvides, implements
from zope.publisher.interfaces import IRequest
from zope.publisher.browser import BrowserView

HEAD_TAG = re.compile('<head>', re.IGNORECASE)
META_CT_TAG = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'

class BaseView(BrowserView):
    """
    Views are multi-adapters for context and request objects.
    """
    def __init__(self, context, request):
        self.context = context
        self.request = request
        self.request.response = queryUtility(IResponseFactory, default=Response)('')


class View(BaseView):
    """
    Wraps generated body in response object.
    """
    implements(IView)

    def render(self):
        """
        Return the content provided by this view.
        """
        raise NotImplementedError

    def __call__(self):
        result = self.render()
        
        if isinstance(result, unicode):
            result = result.encode('utf-8')
        
        self.request.response.body = result
        return self.request.response


class PageTemplateView(View):
    """
    Helper class for views.
    """
    template = None
    
    def __init__(self, context, request):
        super(PageTemplateView, self).__init__(context, request)
        
        ## request and response objects must imitate Zope3 object
        ## because z3c.pt can only work with such objects
        alsoProvides(self.request, IRequest)
        
        response = self.request.response
        response.getHeader = response.headers.__getitem__
        response.setHeader = response.headers.__setitem__        
    
    def render(self):
        """
        Return rendered template as view.
        """
        result = ''
        if self.template is not None:
            result = self.template()
            
        if isinstance(result, unicode):
            result = HEAD_TAG.sub('<head>'+META_CT_TAG, result)
            result = result.encode('utf-8', 'xmlcharrefreplace')
        
        return result
